{
 "cells": [
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T08:06:06.996226Z",
     "start_time": "2025-03-06T08:06:01.839604Z"
    }
   },
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=9, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.1\n",
      "numpy 2.0.1\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.1\n",
      "torch 2.6.0+cu126\n",
      "cuda:0\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备数据"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:15:59.040353Z",
     "start_time": "2025-03-06T10:15:59.027498Z"
    }
   },
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing(data_home='data')\n",
    "\n",
    "print(housing.data.shape)\n",
    "print(housing.target.shape)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(20640, 8)\n",
      "(20640,)\n"
     ]
    }
   ],
   "execution_count": 33
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T08:06:25.443635Z",
     "start_time": "2025-03-06T08:06:25.438412Z"
    }
   },
   "source": [
    "# print(housing.data[0:5])\n",
    "import pprint  #打印的格式比较 好看\n",
    "\n",
    "pprint.pprint(housing.data[0:2])\n",
    "print('-'*50)\n",
    "pprint.pprint(housing.target[0:2])"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "array([[ 8.32520000e+00,  4.10000000e+01,  6.98412698e+00,\n",
      "         1.02380952e+00,  3.22000000e+02,  2.55555556e+00,\n",
      "         3.78800000e+01, -1.22230000e+02],\n",
      "       [ 8.30140000e+00,  2.10000000e+01,  6.23813708e+00,\n",
      "         9.71880492e-01,  2.40100000e+03,  2.10984183e+00,\n",
      "         3.78600000e+01, -1.22220000e+02]])\n",
      "--------------------------------------------------\n",
      "array([4.526, 3.585])\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T08:25:48.102340Z",
     "start_time": "2025-03-06T08:25:48.031516Z"
    }
   },
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "#拆分训练集和测试集，random_state是随机种子,同样的随机数种子，是为了得到同样的随机值\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(\n",
    "    housing.data, housing.target, random_state = 7)\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state = 11)\n",
    "\n",
    "\n",
    "dataset_maps = {\n",
    "    \"train\": [x_train, y_train], #训练集\n",
    "    \"valid\": [x_valid, y_valid], #验证集\n",
    "    \"test\": [x_test, y_test], #测试集\n",
    "} #把3个数据集都放到字典中\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(11610, 8) (11610,)\n",
      "(3870, 8) (3870,)\n",
      "(5160, 8) (5160,)\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "source": [
    "type(x_train)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T08:25:48.991501Z",
     "start_time": "2025-03-06T08:25:48.984477Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T08:25:50.008750Z",
     "start_time": "2025-03-06T08:25:49.991546Z"
    }
   },
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler() #标准化\n",
    "scaler.fit(x_train) #fit和fit_transform的区别，fit是计算均值和方差，fit_transform是先fit，然后transform"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StandardScaler()"
      ],
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>StandardScaler</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "source": [
    "np.array(1).shape"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T08:25:56.289272Z",
     "start_time": "2025-03-06T08:25:56.284597Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 构建数据集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:45:48.484825Z",
     "start_time": "2025-03-06T10:45:48.476829Z"
    }
   },
   "source": [
    "#构建私有数据集，就需要用如下方式\n",
    "from torch.utils.data import Dataset\n",
    "\n",
    "class HousingDataset(Dataset):\n",
    "    def __init__(self, mode='train'):\n",
    "        self.x, self.y = dataset_maps[mode] #x,y都是ndarray类型\n",
    "        self.x = torch.from_numpy(scaler.transform(self.x)).float() #from_numpy将NumPy数组转换成PyTorch张量,scaler.transform是对数据进行标准化\n",
    "        self.y = torch.from_numpy(self.y).float().reshape(-1, 1) #处理为多行1列的tensor类型,因为__getitem__切片时需要\n",
    "            \n",
    "    def __len__(self): #必须写\n",
    "        return len(self.x) #返回数据集的长度,0维的size\n",
    "    \n",
    "    def __getitem__(self, idx): #idx是索引，返回的是数据和标签，这里是一个样本\n",
    "        return self.x[idx], self.y[idx]\n",
    "    \n",
    "#train_ds是dataset类型的数据，与前面例子的FashionMNIST类型一致\n",
    "train_ds = HousingDataset(\"train\")\n",
    "valid_ds = HousingDataset(\"valid\")\n",
    "test_ds = HousingDataset(\"test\")"
   ],
   "outputs": [],
   "execution_count": 34
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:45:48.988961Z",
     "start_time": "2025-03-06T10:45:48.983976Z"
    }
   },
   "cell_type": "code",
   "source": "type(train_ds)\n",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "__main__.HousingDataset"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 35
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:45:49.457531Z",
     "start_time": "2025-03-06T10:45:49.452514Z"
    }
   },
   "source": "train_ds[1]",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([-0.2981,  0.3523, -0.1092, -0.2506, -0.0341, -0.0060,  1.0806, -1.0611]),\n",
       " tensor([1.5140]))"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 36
  },
  {
   "cell_type": "code",
   "source": "train_ds[1][1]",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T10:45:49.814069Z",
     "start_time": "2025-03-06T10:45:49.807127Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([1.5140])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 37
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:52:32.612777Z",
     "start_time": "2025-03-06T10:52:32.608199Z"
    }
   },
   "source": [
    "from torch.utils.data import DataLoader\n",
    "\n",
    "#放到DataLoader中的train_ds, valid_ds, test_ds都是dataset类型的数据\n",
    "batch_size = 16 #batch_size是可以调的超参数\n",
    "train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)\n",
    "val_loader = DataLoader(valid_ds, batch_size=batch_size, shuffle=False)\n",
    "test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False)"
   ],
   "outputs": [],
   "execution_count": 43
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:52:37.425491Z",
     "start_time": "2025-03-06T10:52:37.420716Z"
    }
   },
   "source": [
    "#回归模型我们只需要1个数\n",
    "\n",
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self, input_dim=8):\n",
    "        super().__init__()\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(input_dim, 30),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(30, 1)\n",
    "            )\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # x.shape [batch size, 8]\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        # logits.shape [batch size, 1]\n",
    "        return logits"
   ],
   "outputs": [],
   "execution_count": 44
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:52:37.766672Z",
     "start_time": "2025-03-06T10:52:37.762238Z"
    }
   },
   "cell_type": "code",
   "source": "8*30+30+30*1+1",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "301"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 45
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:52:38.018356Z",
     "start_time": "2025-03-06T10:52:38.013361Z"
    }
   },
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ],
   "outputs": [],
   "execution_count": 46
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:52:38.219423Z",
     "start_time": "2025-03-06T10:52:38.214657Z"
    }
   },
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        #回归问题不需要准确率\n",
    "    return np.mean(loss_list)\n"
   ],
   "outputs": [],
   "execution_count": 47
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:55:06.063309Z",
     "start_time": "2025-03-06T10:52:38.396674Z"
    }
   },
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:#11610/16=726\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas) #得到预测值\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    " \n",
    "                loss = loss.cpu().item() #转为cpu类型，item()是取值\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "\n",
    "                    # 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(-val_loss) #根据验证集的损失来实现早停\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 100\n",
    "\n",
    "model = NeuralNetwork()\n",
    "\n",
    "# 1. 定义损失函数 采用MSE损失,均方误差\n",
    "loss_fct = nn.MSELoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10, min_delta=1e-3)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    "    )"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/72600 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "713fa349f9294851b4e5b8c193e47077"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Early stop at epoch 60 / global_step 43560\n"
     ]
    }
   ],
   "execution_count": 48
  },
  {
   "cell_type": "code",
   "source": [
    "record"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T10:55:06.116374Z",
     "start_time": "2025-03-06T10:55:06.064281Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'train': [{'loss': 3.3324742317199707, 'step': 0},\n",
       "  {'loss': 6.982382297515869, 'step': 1},\n",
       "  {'loss': 9.572691917419434, 'step': 2},\n",
       "  {'loss': 3.4466142654418945, 'step': 3},\n",
       "  {'loss': 5.54802942276001, 'step': 4},\n",
       "  {'loss': 3.9321999549865723, 'step': 5},\n",
       "  {'loss': 5.118983745574951, 'step': 6},\n",
       "  {'loss': 4.3391313552856445, 'step': 7},\n",
       "  {'loss': 5.05194616317749, 'step': 8},\n",
       "  {'loss': 5.415342330932617, 'step': 9},\n",
       "  {'loss': 5.390442371368408, 'step': 10},\n",
       "  {'loss': 3.664006471633911, 'step': 11},\n",
       "  {'loss': 2.0984489917755127, 'step': 12},\n",
       "  {'loss': 3.2323923110961914, 'step': 13},\n",
       "  {'loss': 3.3669910430908203, 'step': 14},\n",
       "  {'loss': 2.9607250690460205, 'step': 15},\n",
       "  {'loss': 1.965924859046936, 'step': 16},\n",
       "  {'loss': 4.357116222381592, 'step': 17},\n",
       "  {'loss': 3.746685266494751, 'step': 18},\n",
       "  {'loss': 5.241276741027832, 'step': 19},\n",
       "  {'loss': 14.853094100952148, 'step': 20},\n",
       "  {'loss': 2.941668748855591, 'step': 21},\n",
       "  {'loss': 3.216686725616455, 'step': 22},\n",
       "  {'loss': 0.737837016582489, 'step': 23},\n",
       "  {'loss': 2.7311339378356934, 'step': 24},\n",
       "  {'loss': 1.8104314804077148, 'step': 25},\n",
       "  {'loss': 1.227081060409546, 'step': 26},\n",
       "  {'loss': 1.616166114807129, 'step': 27},\n",
       "  {'loss': 2.3972811698913574, 'step': 28},\n",
       "  {'loss': 6.5311760902404785, 'step': 29},\n",
       "  {'loss': 1.218949794769287, 'step': 30},\n",
       "  {'loss': 0.4864726662635803, 'step': 31},\n",
       "  {'loss': 1.8999733924865723, 'step': 32},\n",
       "  {'loss': 1.4216479063034058, 'step': 33},\n",
       "  {'loss': 1.396026372909546, 'step': 34},\n",
       "  {'loss': 0.5069418549537659, 'step': 35},\n",
       "  {'loss': 1.1296555995941162, 'step': 36},\n",
       "  {'loss': 1.403235912322998, 'step': 37},\n",
       "  {'loss': 0.38439691066741943, 'step': 38},\n",
       "  {'loss': 1.1457303762435913, 'step': 39},\n",
       "  {'loss': 2.2675223350524902, 'step': 40},\n",
       "  {'loss': 1.6339821815490723, 'step': 41},\n",
       "  {'loss': 0.4231317341327667, 'step': 42},\n",
       "  {'loss': 6.9662652015686035, 'step': 43},\n",
       "  {'loss': 2.9739222526550293, 'step': 44},\n",
       "  {'loss': 1.004027247428894, 'step': 45},\n",
       "  {'loss': 0.7266217470169067, 'step': 46},\n",
       "  {'loss': 1.5955150127410889, 'step': 47},\n",
       "  {'loss': 0.8203713893890381, 'step': 48},\n",
       "  {'loss': 0.8195321559906006, 'step': 49},\n",
       "  {'loss': 0.882017195224762, 'step': 50},\n",
       "  {'loss': 0.9399021863937378, 'step': 51},\n",
       "  {'loss': 0.8593010902404785, 'step': 52},\n",
       "  {'loss': 0.9765236973762512, 'step': 53},\n",
       "  {'loss': 0.7097693681716919, 'step': 54},\n",
       "  {'loss': 0.6975784301757812, 'step': 55},\n",
       "  {'loss': 2.1621057987213135, 'step': 56},\n",
       "  {'loss': 6.161765098571777, 'step': 57},\n",
       "  {'loss': 3.832885503768921, 'step': 58},\n",
       "  {'loss': 0.8353111743927002, 'step': 59},\n",
       "  {'loss': 0.6201527118682861, 'step': 60},\n",
       "  {'loss': 0.9479308128356934, 'step': 61},\n",
       "  {'loss': 1.1764999628067017, 'step': 62},\n",
       "  {'loss': 0.9361634254455566, 'step': 63},\n",
       "  {'loss': 1.1625332832336426, 'step': 64},\n",
       "  {'loss': 0.992619514465332, 'step': 65},\n",
       "  {'loss': 0.4790608584880829, 'step': 66},\n",
       "  {'loss': 0.6973583698272705, 'step': 67},\n",
       "  {'loss': 0.6023935079574585, 'step': 68},\n",
       "  {'loss': 0.5496131181716919, 'step': 69},\n",
       "  {'loss': 0.8615556359291077, 'step': 70},\n",
       "  {'loss': 0.8017969131469727, 'step': 71},\n",
       "  {'loss': 0.9272614121437073, 'step': 72},\n",
       "  {'loss': 0.8006595969200134, 'step': 73},\n",
       "  {'loss': 0.8862935304641724, 'step': 74},\n",
       "  {'loss': 0.6977887153625488, 'step': 75},\n",
       "  {'loss': 1.409595251083374, 'step': 76},\n",
       "  {'loss': 0.9087924957275391, 'step': 77},\n",
       "  {'loss': 0.6243245601654053, 'step': 78},\n",
       "  {'loss': 0.8761963248252869, 'step': 79},\n",
       "  {'loss': 1.068907618522644, 'step': 80},\n",
       "  {'loss': 1.048366665840149, 'step': 81},\n",
       "  {'loss': 0.4846743047237396, 'step': 82},\n",
       "  {'loss': 0.9391227960586548, 'step': 83},\n",
       "  {'loss': 1.2673428058624268, 'step': 84},\n",
       "  {'loss': 0.522541880607605, 'step': 85},\n",
       "  {'loss': 0.9605014324188232, 'step': 86},\n",
       "  {'loss': 0.4300370216369629, 'step': 87},\n",
       "  {'loss': 0.4238203167915344, 'step': 88},\n",
       "  {'loss': 1.656697392463684, 'step': 89},\n",
       "  {'loss': 0.7719748020172119, 'step': 90},\n",
       "  {'loss': 0.6148617267608643, 'step': 91},\n",
       "  {'loss': 0.3949173390865326, 'step': 92},\n",
       "  {'loss': 0.4723759591579437, 'step': 93},\n",
       "  {'loss': 0.503369927406311, 'step': 94},\n",
       "  {'loss': 0.8408592343330383, 'step': 95},\n",
       "  {'loss': 0.5043403506278992, 'step': 96},\n",
       "  {'loss': 1.433121681213379, 'step': 97},\n",
       "  {'loss': 0.6106711626052856, 'step': 98},\n",
       "  {'loss': 1.891494870185852, 'step': 99},\n",
       "  {'loss': 0.33267635107040405, 'step': 100},\n",
       "  {'loss': 0.3886908292770386, 'step': 101},\n",
       "  {'loss': 0.41432932019233704, 'step': 102},\n",
       "  {'loss': 0.5688297748565674, 'step': 103},\n",
       "  {'loss': 0.43142902851104736, 'step': 104},\n",
       "  {'loss': 0.7641443014144897, 'step': 105},\n",
       "  {'loss': 0.5478437542915344, 'step': 106},\n",
       "  {'loss': 0.4560917019844055, 'step': 107},\n",
       "  {'loss': 0.5201743245124817, 'step': 108},\n",
       "  {'loss': 1.3397914171218872, 'step': 109},\n",
       "  {'loss': 0.26792973279953003, 'step': 110},\n",
       "  {'loss': 0.8429175019264221, 'step': 111},\n",
       "  {'loss': 0.5612753629684448, 'step': 112},\n",
       "  {'loss': 0.5414046049118042, 'step': 113},\n",
       "  {'loss': 0.7908703684806824, 'step': 114},\n",
       "  {'loss': 0.47456225752830505, 'step': 115},\n",
       "  {'loss': 1.220268964767456, 'step': 116},\n",
       "  {'loss': 0.3652181923389435, 'step': 117},\n",
       "  {'loss': 0.34364598989486694, 'step': 118},\n",
       "  {'loss': 0.6780569553375244, 'step': 119},\n",
       "  {'loss': 1.5827610492706299, 'step': 120},\n",
       "  {'loss': 0.24790643155574799, 'step': 121},\n",
       "  {'loss': 0.5125564336776733, 'step': 122},\n",
       "  {'loss': 1.099616527557373, 'step': 123},\n",
       "  {'loss': 0.3649952709674835, 'step': 124},\n",
       "  {'loss': 2.8502988815307617, 'step': 125},\n",
       "  {'loss': 0.22209808230400085, 'step': 126},\n",
       "  {'loss': 1.5207984447479248, 'step': 127},\n",
       "  {'loss': 0.70718914270401, 'step': 128},\n",
       "  {'loss': 0.5091909170150757, 'step': 129},\n",
       "  {'loss': 0.6843268275260925, 'step': 130},\n",
       "  {'loss': 0.3153870701789856, 'step': 131},\n",
       "  {'loss': 0.35596781969070435, 'step': 132},\n",
       "  {'loss': 0.4199368953704834, 'step': 133},\n",
       "  {'loss': 0.5617640018463135, 'step': 134},\n",
       "  {'loss': 1.1726460456848145, 'step': 135},\n",
       "  {'loss': 0.5627456903457642, 'step': 136},\n",
       "  {'loss': 0.8894386291503906, 'step': 137},\n",
       "  {'loss': 0.8222339153289795, 'step': 138},\n",
       "  {'loss': 0.5233850479125977, 'step': 139},\n",
       "  {'loss': 0.9195185899734497, 'step': 140},\n",
       "  {'loss': 0.853492796421051, 'step': 141},\n",
       "  {'loss': 0.3491036295890808, 'step': 142},\n",
       "  {'loss': 0.5206612348556519, 'step': 143},\n",
       "  {'loss': 0.8348606824874878, 'step': 144},\n",
       "  {'loss': 1.0923383235931396, 'step': 145},\n",
       "  {'loss': 0.7329461574554443, 'step': 146},\n",
       "  {'loss': 1.6090867519378662, 'step': 147},\n",
       "  {'loss': 0.6143540740013123, 'step': 148},\n",
       "  {'loss': 0.5751110911369324, 'step': 149},\n",
       "  {'loss': 0.2043614387512207, 'step': 150},\n",
       "  {'loss': 0.6422539949417114, 'step': 151},\n",
       "  {'loss': 1.1423618793487549, 'step': 152},\n",
       "  {'loss': 2.040736436843872, 'step': 153},\n",
       "  {'loss': 0.4139595329761505, 'step': 154},\n",
       "  {'loss': 0.4539474844932556, 'step': 155},\n",
       "  {'loss': 0.6006650924682617, 'step': 156},\n",
       "  {'loss': 0.8758072257041931, 'step': 157},\n",
       "  {'loss': 0.8465036153793335, 'step': 158},\n",
       "  {'loss': 0.990445613861084, 'step': 159},\n",
       "  {'loss': 0.36188334226608276, 'step': 160},\n",
       "  {'loss': 1.3837707042694092, 'step': 161},\n",
       "  {'loss': 0.4836423695087433, 'step': 162},\n",
       "  {'loss': 0.7495912313461304, 'step': 163},\n",
       "  {'loss': 0.6495571136474609, 'step': 164},\n",
       "  {'loss': 0.46560901403427124, 'step': 165},\n",
       "  {'loss': 0.46851128339767456, 'step': 166},\n",
       "  {'loss': 0.41728153824806213, 'step': 167},\n",
       "  {'loss': 0.2929230034351349, 'step': 168},\n",
       "  {'loss': 0.48213496804237366, 'step': 169},\n",
       "  {'loss': 0.3157476782798767, 'step': 170},\n",
       "  {'loss': 0.24621200561523438, 'step': 171},\n",
       "  {'loss': 0.2535877823829651, 'step': 172},\n",
       "  {'loss': 0.8731553554534912, 'step': 173},\n",
       "  {'loss': 0.39318200945854187, 'step': 174},\n",
       "  {'loss': 0.22376775741577148, 'step': 175},\n",
       "  {'loss': 0.447623074054718, 'step': 176},\n",
       "  {'loss': 1.289628505706787, 'step': 177},\n",
       "  {'loss': 0.8828558921813965, 'step': 178},\n",
       "  {'loss': 0.3690297603607178, 'step': 179},\n",
       "  {'loss': 1.8427045345306396, 'step': 180},\n",
       "  {'loss': 0.8453102111816406, 'step': 181},\n",
       "  {'loss': 0.8770781755447388, 'step': 182},\n",
       "  {'loss': 0.6876528859138489, 'step': 183},\n",
       "  {'loss': 0.725476861000061, 'step': 184},\n",
       "  {'loss': 1.1990883350372314, 'step': 185},\n",
       "  {'loss': 0.6094306707382202, 'step': 186},\n",
       "  {'loss': 1.215173602104187, 'step': 187},\n",
       "  {'loss': 0.4141116738319397, 'step': 188},\n",
       "  {'loss': 0.5008690357208252, 'step': 189},\n",
       "  {'loss': 0.8726736307144165, 'step': 190},\n",
       "  {'loss': 0.43668025732040405, 'step': 191},\n",
       "  {'loss': 1.2507991790771484, 'step': 192},\n",
       "  {'loss': 0.36141064763069153, 'step': 193},\n",
       "  {'loss': 0.5639787316322327, 'step': 194},\n",
       "  {'loss': 1.085456132888794, 'step': 195},\n",
       "  {'loss': 0.9248135685920715, 'step': 196},\n",
       "  {'loss': 0.35072290897369385, 'step': 197},\n",
       "  {'loss': 0.30854249000549316, 'step': 198},\n",
       "  {'loss': 0.5549358129501343, 'step': 199},\n",
       "  {'loss': 0.6983405351638794, 'step': 200},\n",
       "  {'loss': 0.8413885831832886, 'step': 201},\n",
       "  {'loss': 0.49805545806884766, 'step': 202},\n",
       "  {'loss': 0.18776348233222961, 'step': 203},\n",
       "  {'loss': 0.7823565006256104, 'step': 204},\n",
       "  {'loss': 0.6637091040611267, 'step': 205},\n",
       "  {'loss': 0.7924615144729614, 'step': 206},\n",
       "  {'loss': 0.7033772468566895, 'step': 207},\n",
       "  {'loss': 0.3669220805168152, 'step': 208},\n",
       "  {'loss': 1.2795019149780273, 'step': 209},\n",
       "  {'loss': 0.5636466145515442, 'step': 210},\n",
       "  {'loss': 0.6283979415893555, 'step': 211},\n",
       "  {'loss': 0.652856707572937, 'step': 212},\n",
       "  {'loss': 1.1981666088104248, 'step': 213},\n",
       "  {'loss': 0.6297304034233093, 'step': 214},\n",
       "  {'loss': 0.44308537244796753, 'step': 215},\n",
       "  {'loss': 0.44673240184783936, 'step': 216},\n",
       "  {'loss': 0.7399044036865234, 'step': 217},\n",
       "  {'loss': 0.6022312641143799, 'step': 218},\n",
       "  {'loss': 0.5987251996994019, 'step': 219},\n",
       "  {'loss': 0.32005774974823, 'step': 220},\n",
       "  {'loss': 0.6030659675598145, 'step': 221},\n",
       "  {'loss': 0.4096996784210205, 'step': 222},\n",
       "  {'loss': 0.3962186574935913, 'step': 223},\n",
       "  {'loss': 0.4185161888599396, 'step': 224},\n",
       "  {'loss': 1.5001111030578613, 'step': 225},\n",
       "  {'loss': 0.5472989082336426, 'step': 226},\n",
       "  {'loss': 0.20615951716899872, 'step': 227},\n",
       "  {'loss': 0.35953909158706665, 'step': 228},\n",
       "  {'loss': 0.7368499636650085, 'step': 229},\n",
       "  {'loss': 0.6929734945297241, 'step': 230},\n",
       "  {'loss': 0.4993756115436554, 'step': 231},\n",
       "  {'loss': 0.5108731389045715, 'step': 232},\n",
       "  {'loss': 0.6828191876411438, 'step': 233},\n",
       "  {'loss': 0.5730926394462585, 'step': 234},\n",
       "  {'loss': 0.12185600399971008, 'step': 235},\n",
       "  {'loss': 0.49524396657943726, 'step': 236},\n",
       "  {'loss': 0.24462175369262695, 'step': 237},\n",
       "  {'loss': 0.5285546779632568, 'step': 238},\n",
       "  {'loss': 0.2091192603111267, 'step': 239},\n",
       "  {'loss': 0.36441570520401, 'step': 240},\n",
       "  {'loss': 0.4051477015018463, 'step': 241},\n",
       "  {'loss': 0.8631610870361328, 'step': 242},\n",
       "  {'loss': 0.6962200403213501, 'step': 243},\n",
       "  {'loss': 0.4607524275779724, 'step': 244},\n",
       "  {'loss': 0.730822741985321, 'step': 245},\n",
       "  {'loss': 0.40560096502304077, 'step': 246},\n",
       "  {'loss': 0.5849281549453735, 'step': 247},\n",
       "  {'loss': 0.5706913471221924, 'step': 248},\n",
       "  {'loss': 0.5804156064987183, 'step': 249},\n",
       "  {'loss': 0.5455363392829895, 'step': 250},\n",
       "  {'loss': 0.6025027632713318, 'step': 251},\n",
       "  {'loss': 0.6578962802886963, 'step': 252},\n",
       "  {'loss': 0.416846364736557, 'step': 253},\n",
       "  {'loss': 0.37858888506889343, 'step': 254},\n",
       "  {'loss': 0.1808544248342514, 'step': 255},\n",
       "  {'loss': 0.4376338720321655, 'step': 256},\n",
       "  {'loss': 0.9229727387428284, 'step': 257},\n",
       "  {'loss': 0.36222970485687256, 'step': 258},\n",
       "  {'loss': 0.5432062149047852, 'step': 259},\n",
       "  {'loss': 0.4030919075012207, 'step': 260},\n",
       "  {'loss': 0.5077053308486938, 'step': 261},\n",
       "  {'loss': 0.26201143860816956, 'step': 262},\n",
       "  {'loss': 0.48361217975616455, 'step': 263},\n",
       "  {'loss': 0.29821473360061646, 'step': 264},\n",
       "  {'loss': 0.8519881963729858, 'step': 265},\n",
       "  {'loss': 0.28459036350250244, 'step': 266},\n",
       "  {'loss': 0.38251763582229614, 'step': 267},\n",
       "  {'loss': 0.7597658634185791, 'step': 268},\n",
       "  {'loss': 0.2500295341014862, 'step': 269},\n",
       "  {'loss': 0.2080238312482834, 'step': 270},\n",
       "  {'loss': 0.8920451402664185, 'step': 271},\n",
       "  {'loss': 0.5023524165153503, 'step': 272},\n",
       "  {'loss': 0.8840103149414062, 'step': 273},\n",
       "  {'loss': 1.102287769317627, 'step': 274},\n",
       "  {'loss': 0.5708620548248291, 'step': 275},\n",
       "  {'loss': 0.5946640372276306, 'step': 276},\n",
       "  {'loss': 0.5914566516876221, 'step': 277},\n",
       "  {'loss': 0.9551805257797241, 'step': 278},\n",
       "  {'loss': 0.3517666459083557, 'step': 279},\n",
       "  {'loss': 0.5013841986656189, 'step': 280},\n",
       "  {'loss': 0.4123116135597229, 'step': 281},\n",
       "  {'loss': 1.107469916343689, 'step': 282},\n",
       "  {'loss': 0.9654507040977478, 'step': 283},\n",
       "  {'loss': 0.9049711227416992, 'step': 284},\n",
       "  {'loss': 0.3100089430809021, 'step': 285},\n",
       "  {'loss': 0.9311565160751343, 'step': 286},\n",
       "  {'loss': 0.3878988027572632, 'step': 287},\n",
       "  {'loss': 0.29288250207901, 'step': 288},\n",
       "  {'loss': 0.3574208617210388, 'step': 289},\n",
       "  {'loss': 0.6084825396537781, 'step': 290},\n",
       "  {'loss': 0.6013326644897461, 'step': 291},\n",
       "  {'loss': 0.3168480396270752, 'step': 292},\n",
       "  {'loss': 0.7614114284515381, 'step': 293},\n",
       "  {'loss': 0.46367815136909485, 'step': 294},\n",
       "  {'loss': 0.7756961584091187, 'step': 295},\n",
       "  {'loss': 1.0692274570465088, 'step': 296},\n",
       "  {'loss': 0.6669880747795105, 'step': 297},\n",
       "  {'loss': 1.0937987565994263, 'step': 298},\n",
       "  {'loss': 0.09362912178039551, 'step': 299},\n",
       "  {'loss': 0.5068982243537903, 'step': 300},\n",
       "  {'loss': 0.339647501707077, 'step': 301},\n",
       "  {'loss': 0.7933177947998047, 'step': 302},\n",
       "  {'loss': 0.44555050134658813, 'step': 303},\n",
       "  {'loss': 0.7127025127410889, 'step': 304},\n",
       "  {'loss': 0.6942082643508911, 'step': 305},\n",
       "  {'loss': 0.6268556118011475, 'step': 306},\n",
       "  {'loss': 0.39549440145492554, 'step': 307},\n",
       "  {'loss': 0.47458118200302124, 'step': 308},\n",
       "  {'loss': 0.3270754814147949, 'step': 309},\n",
       "  {'loss': 0.49395766854286194, 'step': 310},\n",
       "  {'loss': 0.4052470326423645, 'step': 311},\n",
       "  {'loss': 2.312335968017578, 'step': 312},\n",
       "  {'loss': 0.6786929965019226, 'step': 313},\n",
       "  {'loss': 0.9627508521080017, 'step': 314},\n",
       "  {'loss': 0.22496159374713898, 'step': 315},\n",
       "  {'loss': 0.306710422039032, 'step': 316},\n",
       "  {'loss': 0.380190908908844, 'step': 317},\n",
       "  {'loss': 0.6125452518463135, 'step': 318},\n",
       "  {'loss': 0.2873823940753937, 'step': 319},\n",
       "  {'loss': 0.40710484981536865, 'step': 320},\n",
       "  {'loss': 0.46088075637817383, 'step': 321},\n",
       "  {'loss': 1.1487598419189453, 'step': 322},\n",
       "  {'loss': 0.14910629391670227, 'step': 323},\n",
       "  {'loss': 0.5216102600097656, 'step': 324},\n",
       "  {'loss': 2.618744373321533, 'step': 325},\n",
       "  {'loss': 0.3745173513889313, 'step': 326},\n",
       "  {'loss': 1.0373083353042603, 'step': 327},\n",
       "  {'loss': 1.275211215019226, 'step': 328},\n",
       "  {'loss': 0.2489570677280426, 'step': 329},\n",
       "  {'loss': 0.9026826620101929, 'step': 330},\n",
       "  {'loss': 1.1970994472503662, 'step': 331},\n",
       "  {'loss': 0.6464635133743286, 'step': 332},\n",
       "  {'loss': 0.7974812984466553, 'step': 333},\n",
       "  {'loss': 0.5434930324554443, 'step': 334},\n",
       "  {'loss': 0.5481840372085571, 'step': 335},\n",
       "  {'loss': 0.4132137894630432, 'step': 336},\n",
       "  {'loss': 0.20295953750610352, 'step': 337},\n",
       "  {'loss': 0.27414292097091675, 'step': 338},\n",
       "  {'loss': 0.8068504929542542, 'step': 339},\n",
       "  {'loss': 0.3440634608268738, 'step': 340},\n",
       "  {'loss': 0.4688079357147217, 'step': 341},\n",
       "  {'loss': 0.9504454135894775, 'step': 342},\n",
       "  {'loss': 0.2743885815143585, 'step': 343},\n",
       "  {'loss': 0.43075090646743774, 'step': 344},\n",
       "  {'loss': 1.2164576053619385, 'step': 345},\n",
       "  {'loss': 0.33491021394729614, 'step': 346},\n",
       "  {'loss': 0.6870468854904175, 'step': 347},\n",
       "  {'loss': 0.6425930261611938, 'step': 348},\n",
       "  {'loss': 0.2885037660598755, 'step': 349},\n",
       "  {'loss': 0.7806259393692017, 'step': 350},\n",
       "  {'loss': 0.15999490022659302, 'step': 351},\n",
       "  {'loss': 0.32213765382766724, 'step': 352},\n",
       "  {'loss': 0.4034593105316162, 'step': 353},\n",
       "  {'loss': 0.2578626871109009, 'step': 354},\n",
       "  {'loss': 0.4614734649658203, 'step': 355},\n",
       "  {'loss': 0.8757821321487427, 'step': 356},\n",
       "  {'loss': 1.2527310848236084, 'step': 357},\n",
       "  {'loss': 0.4282319247722626, 'step': 358},\n",
       "  {'loss': 0.36921119689941406, 'step': 359},\n",
       "  {'loss': 0.36971884965896606, 'step': 360},\n",
       "  {'loss': 0.2601882219314575, 'step': 361},\n",
       "  {'loss': 0.48339205980300903, 'step': 362},\n",
       "  {'loss': 0.7937740087509155, 'step': 363},\n",
       "  {'loss': 0.5568493604660034, 'step': 364},\n",
       "  {'loss': 0.8333208560943604, 'step': 365},\n",
       "  {'loss': 0.3775012195110321, 'step': 366},\n",
       "  {'loss': 0.47974053025245667, 'step': 367},\n",
       "  {'loss': 0.4118647575378418, 'step': 368},\n",
       "  {'loss': 1.0185552835464478, 'step': 369},\n",
       "  {'loss': 0.8325579166412354, 'step': 370},\n",
       "  {'loss': 0.9483100771903992, 'step': 371},\n",
       "  {'loss': 0.8566147089004517, 'step': 372},\n",
       "  {'loss': 0.7376701235771179, 'step': 373},\n",
       "  {'loss': 0.5838041305541992, 'step': 374},\n",
       "  {'loss': 0.9548225998878479, 'step': 375},\n",
       "  {'loss': 0.2665333151817322, 'step': 376},\n",
       "  {'loss': 0.20885449647903442, 'step': 377},\n",
       "  {'loss': 2.94757080078125, 'step': 378},\n",
       "  {'loss': 1.3179223537445068, 'step': 379},\n",
       "  {'loss': 0.22831599414348602, 'step': 380},\n",
       "  {'loss': 0.2962897717952728, 'step': 381},\n",
       "  {'loss': 0.4667164385318756, 'step': 382},\n",
       "  {'loss': 0.2404395192861557, 'step': 383},\n",
       "  {'loss': 0.4902334213256836, 'step': 384},\n",
       "  {'loss': 0.21562117338180542, 'step': 385},\n",
       "  {'loss': 0.3604891300201416, 'step': 386},\n",
       "  {'loss': 0.48604443669319153, 'step': 387},\n",
       "  {'loss': 0.2533625364303589, 'step': 388},\n",
       "  {'loss': 0.5430064797401428, 'step': 389},\n",
       "  {'loss': 0.44154128432273865, 'step': 390},\n",
       "  {'loss': 0.7518156170845032, 'step': 391},\n",
       "  {'loss': 0.21749314665794373, 'step': 392},\n",
       "  {'loss': 0.20649310946464539, 'step': 393},\n",
       "  {'loss': 0.3106956481933594, 'step': 394},\n",
       "  {'loss': 0.23596805334091187, 'step': 395},\n",
       "  {'loss': 0.2000603973865509, 'step': 396},\n",
       "  {'loss': 0.47570210695266724, 'step': 397},\n",
       "  {'loss': 0.31658634543418884, 'step': 398},\n",
       "  {'loss': 0.8921372890472412, 'step': 399},\n",
       "  {'loss': 0.4301292300224304, 'step': 400},\n",
       "  {'loss': 1.1955162286758423, 'step': 401},\n",
       "  {'loss': 0.5010460615158081, 'step': 402},\n",
       "  {'loss': 0.40980738401412964, 'step': 403},\n",
       "  {'loss': 0.5123128890991211, 'step': 404},\n",
       "  {'loss': 0.8032885193824768, 'step': 405},\n",
       "  {'loss': 0.6273396015167236, 'step': 406},\n",
       "  {'loss': 0.4930739104747772, 'step': 407},\n",
       "  {'loss': 0.3132113814353943, 'step': 408},\n",
       "  {'loss': 0.23558707535266876, 'step': 409},\n",
       "  {'loss': 0.8818122148513794, 'step': 410},\n",
       "  {'loss': 0.6046096682548523, 'step': 411},\n",
       "  {'loss': 0.2640783190727234, 'step': 412},\n",
       "  {'loss': 1.2482287883758545, 'step': 413},\n",
       "  {'loss': 0.37397944927215576, 'step': 414},\n",
       "  {'loss': 1.308780550956726, 'step': 415},\n",
       "  {'loss': 0.24459408223628998, 'step': 416},\n",
       "  {'loss': 0.34504935145378113, 'step': 417},\n",
       "  {'loss': 0.4396808445453644, 'step': 418},\n",
       "  {'loss': 0.16321665048599243, 'step': 419},\n",
       "  {'loss': 0.6108902096748352, 'step': 420},\n",
       "  {'loss': 0.3174256682395935, 'step': 421},\n",
       "  {'loss': 1.4752132892608643, 'step': 422},\n",
       "  {'loss': 0.40335971117019653, 'step': 423},\n",
       "  {'loss': 0.3319418132305145, 'step': 424},\n",
       "  {'loss': 0.3341388702392578, 'step': 425},\n",
       "  {'loss': 0.46672338247299194, 'step': 426},\n",
       "  {'loss': 0.5019464492797852, 'step': 427},\n",
       "  {'loss': 0.3969902992248535, 'step': 428},\n",
       "  {'loss': 0.7169783115386963, 'step': 429},\n",
       "  {'loss': 0.2981795072555542, 'step': 430},\n",
       "  {'loss': 0.4680367708206177, 'step': 431},\n",
       "  {'loss': 0.5377676486968994, 'step': 432},\n",
       "  {'loss': 0.6156415939331055, 'step': 433},\n",
       "  {'loss': 39.97471618652344, 'step': 434},\n",
       "  {'loss': 0.41483357548713684, 'step': 435},\n",
       "  {'loss': 0.34567418694496155, 'step': 436},\n",
       "  {'loss': 0.21281158924102783, 'step': 437},\n",
       "  {'loss': 1.5835751295089722, 'step': 438},\n",
       "  {'loss': 0.8753514885902405, 'step': 439},\n",
       "  {'loss': 0.4295482039451599, 'step': 440},\n",
       "  {'loss': 0.32674074172973633, 'step': 441},\n",
       "  {'loss': 0.44340336322784424, 'step': 442},\n",
       "  {'loss': 0.8252008557319641, 'step': 443},\n",
       "  {'loss': 0.9132832884788513, 'step': 444},\n",
       "  {'loss': 0.3974129557609558, 'step': 445},\n",
       "  {'loss': 0.8207600116729736, 'step': 446},\n",
       "  {'loss': 0.5952509641647339, 'step': 447},\n",
       "  {'loss': 0.8063754439353943, 'step': 448},\n",
       "  {'loss': 1.095290184020996, 'step': 449},\n",
       "  {'loss': 0.5165997743606567, 'step': 450},\n",
       "  {'loss': 0.6189604997634888, 'step': 451},\n",
       "  {'loss': 1.2097630500793457, 'step': 452},\n",
       "  {'loss': 0.5818772315979004, 'step': 453},\n",
       "  {'loss': 0.3446205258369446, 'step': 454},\n",
       "  {'loss': 1.3075690269470215, 'step': 455},\n",
       "  {'loss': 0.41766148805618286, 'step': 456},\n",
       "  {'loss': 0.735785961151123, 'step': 457},\n",
       "  {'loss': 0.758874773979187, 'step': 458},\n",
       "  {'loss': 0.6013847589492798, 'step': 459},\n",
       "  {'loss': 1.1646562814712524, 'step': 460},\n",
       "  {'loss': 0.741502583026886, 'step': 461},\n",
       "  {'loss': 0.5132318139076233, 'step': 462},\n",
       "  {'loss': 0.23952987790107727, 'step': 463},\n",
       "  {'loss': 0.33825623989105225, 'step': 464},\n",
       "  {'loss': 0.8769877552986145, 'step': 465},\n",
       "  {'loss': 0.45671021938323975, 'step': 466},\n",
       "  {'loss': 0.6290295124053955, 'step': 467},\n",
       "  {'loss': 0.8297971487045288, 'step': 468},\n",
       "  {'loss': 0.8843512535095215, 'step': 469},\n",
       "  {'loss': 0.19482052326202393, 'step': 470},\n",
       "  {'loss': 0.5742299556732178, 'step': 471},\n",
       "  {'loss': 0.40382587909698486, 'step': 472},\n",
       "  {'loss': 0.7304291725158691, 'step': 473},\n",
       "  {'loss': 0.2693461775779724, 'step': 474},\n",
       "  {'loss': 0.228666752576828, 'step': 475},\n",
       "  {'loss': 0.3098629117012024, 'step': 476},\n",
       "  {'loss': 0.5080706477165222, 'step': 477},\n",
       "  {'loss': 1.3080118894577026, 'step': 478},\n",
       "  {'loss': 0.16066846251487732, 'step': 479},\n",
       "  {'loss': 0.574644148349762, 'step': 480},\n",
       "  {'loss': 0.5281932950019836, 'step': 481},\n",
       "  {'loss': 0.31054380536079407, 'step': 482},\n",
       "  {'loss': 0.9706727266311646, 'step': 483},\n",
       "  {'loss': 0.5104933977127075, 'step': 484},\n",
       "  {'loss': 0.511263370513916, 'step': 485},\n",
       "  {'loss': 0.390414834022522, 'step': 486},\n",
       "  {'loss': 0.10969904065132141, 'step': 487},\n",
       "  {'loss': 0.4771980345249176, 'step': 488},\n",
       "  {'loss': 0.28929048776626587, 'step': 489},\n",
       "  {'loss': 0.7690973281860352, 'step': 490},\n",
       "  {'loss': 0.2282462865114212, 'step': 491},\n",
       "  {'loss': 0.5069522857666016, 'step': 492},\n",
       "  {'loss': 0.44613027572631836, 'step': 493},\n",
       "  {'loss': 0.5964013338088989, 'step': 494},\n",
       "  {'loss': 0.7881425619125366, 'step': 495},\n",
       "  {'loss': 0.5545151233673096, 'step': 496},\n",
       "  {'loss': 0.5801581740379333, 'step': 497},\n",
       "  {'loss': 0.5646295547485352, 'step': 498},\n",
       "  {'loss': 0.33366531133651733, 'step': 499},\n",
       "  {'loss': 0.2013821005821228, 'step': 500},\n",
       "  {'loss': 0.28710395097732544, 'step': 501},\n",
       "  {'loss': 0.18841832876205444, 'step': 502},\n",
       "  {'loss': 0.47168052196502686, 'step': 503},\n",
       "  {'loss': 0.337175577878952, 'step': 504},\n",
       "  {'loss': 0.24789877235889435, 'step': 505},\n",
       "  {'loss': 0.39643120765686035, 'step': 506},\n",
       "  {'loss': 0.3936331868171692, 'step': 507},\n",
       "  {'loss': 0.46875932812690735, 'step': 508},\n",
       "  {'loss': 1.0295974016189575, 'step': 509},\n",
       "  {'loss': 0.5730461478233337, 'step': 510},\n",
       "  {'loss': 0.14725032448768616, 'step': 511},\n",
       "  {'loss': 0.37251216173171997, 'step': 512},\n",
       "  {'loss': 0.562523365020752, 'step': 513},\n",
       "  {'loss': 0.6907680034637451, 'step': 514},\n",
       "  {'loss': 0.7470937371253967, 'step': 515},\n",
       "  {'loss': 1.1113152503967285, 'step': 516},\n",
       "  {'loss': 0.6097862720489502, 'step': 517},\n",
       "  {'loss': 0.7693878412246704, 'step': 518},\n",
       "  {'loss': 0.40332457423210144, 'step': 519},\n",
       "  {'loss': 0.5649310350418091, 'step': 520},\n",
       "  {'loss': 0.8838821649551392, 'step': 521},\n",
       "  {'loss': 0.21502795815467834, 'step': 522},\n",
       "  {'loss': 0.26464205980300903, 'step': 523},\n",
       "  {'loss': 0.5770161747932434, 'step': 524},\n",
       "  {'loss': 0.3002662658691406, 'step': 525},\n",
       "  {'loss': 0.9080523252487183, 'step': 526},\n",
       "  {'loss': 0.8613198399543762, 'step': 527},\n",
       "  {'loss': 0.4647008180618286, 'step': 528},\n",
       "  {'loss': 0.14657509326934814, 'step': 529},\n",
       "  {'loss': 0.7212047576904297, 'step': 530},\n",
       "  {'loss': 0.2283037006855011, 'step': 531},\n",
       "  {'loss': 0.3025602400302887, 'step': 532},\n",
       "  {'loss': 0.8804895877838135, 'step': 533},\n",
       "  {'loss': 0.6596055030822754, 'step': 534},\n",
       "  {'loss': 0.27258455753326416, 'step': 535},\n",
       "  {'loss': 0.6665041446685791, 'step': 536},\n",
       "  {'loss': 0.3441527187824249, 'step': 537},\n",
       "  {'loss': 0.23715409636497498, 'step': 538},\n",
       "  {'loss': 0.12671375274658203, 'step': 539},\n",
       "  {'loss': 0.39107489585876465, 'step': 540},\n",
       "  {'loss': 0.2522139549255371, 'step': 541},\n",
       "  {'loss': 0.6140562295913696, 'step': 542},\n",
       "  {'loss': 0.29542648792266846, 'step': 543},\n",
       "  {'loss': 0.777830958366394, 'step': 544},\n",
       "  {'loss': 0.8697474598884583, 'step': 545},\n",
       "  {'loss': 0.47552356123924255, 'step': 546},\n",
       "  {'loss': 0.9106168150901794, 'step': 547},\n",
       "  {'loss': 0.38183891773223877, 'step': 548},\n",
       "  {'loss': 0.25813567638397217, 'step': 549},\n",
       "  {'loss': 0.543724775314331, 'step': 550},\n",
       "  {'loss': 0.44409888982772827, 'step': 551},\n",
       "  {'loss': 0.18575778603553772, 'step': 552},\n",
       "  {'loss': 0.1851121485233307, 'step': 553},\n",
       "  {'loss': 0.7113965749740601, 'step': 554},\n",
       "  {'loss': 0.38913053274154663, 'step': 555},\n",
       "  {'loss': 0.7003487348556519, 'step': 556},\n",
       "  {'loss': 1.410925269126892, 'step': 557},\n",
       "  {'loss': 0.8659983277320862, 'step': 558},\n",
       "  {'loss': 0.2578205466270447, 'step': 559},\n",
       "  {'loss': 0.3738991320133209, 'step': 560},\n",
       "  {'loss': 0.3825356960296631, 'step': 561},\n",
       "  {'loss': 0.6818546056747437, 'step': 562},\n",
       "  {'loss': 0.40913811326026917, 'step': 563},\n",
       "  {'loss': 0.45891183614730835, 'step': 564},\n",
       "  {'loss': 1.3532723188400269, 'step': 565},\n",
       "  {'loss': 1.0864918231964111, 'step': 566},\n",
       "  {'loss': 0.19789990782737732, 'step': 567},\n",
       "  {'loss': 0.782884955406189, 'step': 568},\n",
       "  {'loss': 0.3175555169582367, 'step': 569},\n",
       "  {'loss': 0.39580613374710083, 'step': 570},\n",
       "  {'loss': 0.8279096484184265, 'step': 571},\n",
       "  {'loss': 0.4696478545665741, 'step': 572},\n",
       "  {'loss': 0.3227110505104065, 'step': 573},\n",
       "  {'loss': 0.6328567266464233, 'step': 574},\n",
       "  {'loss': 0.5582181215286255, 'step': 575},\n",
       "  {'loss': 0.8323167562484741, 'step': 576},\n",
       "  {'loss': 0.39396312832832336, 'step': 577},\n",
       "  {'loss': 0.31558316946029663, 'step': 578},\n",
       "  {'loss': 0.727196216583252, 'step': 579},\n",
       "  {'loss': 0.1915595382452011, 'step': 580},\n",
       "  {'loss': 0.34589940309524536, 'step': 581},\n",
       "  {'loss': 0.8264251947402954, 'step': 582},\n",
       "  {'loss': 0.12889191508293152, 'step': 583},\n",
       "  {'loss': 0.8288007974624634, 'step': 584},\n",
       "  {'loss': 0.15707892179489136, 'step': 585},\n",
       "  {'loss': 0.7485255002975464, 'step': 586},\n",
       "  {'loss': 0.5645256042480469, 'step': 587},\n",
       "  {'loss': 0.5103559494018555, 'step': 588},\n",
       "  {'loss': 0.3035486340522766, 'step': 589},\n",
       "  {'loss': 0.32882851362228394, 'step': 590},\n",
       "  {'loss': 0.5532166957855225, 'step': 591},\n",
       "  {'loss': 0.6772974133491516, 'step': 592},\n",
       "  {'loss': 0.4970688223838806, 'step': 593},\n",
       "  {'loss': 0.3069250285625458, 'step': 594},\n",
       "  {'loss': 0.2812912166118622, 'step': 595},\n",
       "  {'loss': 0.21249940991401672, 'step': 596},\n",
       "  {'loss': 1.0280661582946777, 'step': 597},\n",
       "  {'loss': 0.38473859429359436, 'step': 598},\n",
       "  {'loss': 0.3193631172180176, 'step': 599},\n",
       "  {'loss': 0.2904661297798157, 'step': 600},\n",
       "  {'loss': 0.6640594601631165, 'step': 601},\n",
       "  {'loss': 0.6938192844390869, 'step': 602},\n",
       "  {'loss': 0.3725282847881317, 'step': 603},\n",
       "  {'loss': 2.07507061958313, 'step': 604},\n",
       "  {'loss': 0.15369924902915955, 'step': 605},\n",
       "  {'loss': 0.34121406078338623, 'step': 606},\n",
       "  {'loss': 0.25736305117607117, 'step': 607},\n",
       "  {'loss': 0.2504339814186096, 'step': 608},\n",
       "  {'loss': 0.7193186283111572, 'step': 609},\n",
       "  {'loss': 1.2933392524719238, 'step': 610},\n",
       "  {'loss': 0.47290050983428955, 'step': 611},\n",
       "  {'loss': 1.2613306045532227, 'step': 612},\n",
       "  {'loss': 0.2717669904232025, 'step': 613},\n",
       "  {'loss': 0.6557725071907043, 'step': 614},\n",
       "  {'loss': 0.2929965853691101, 'step': 615},\n",
       "  {'loss': 0.7942175269126892, 'step': 616},\n",
       "  {'loss': 0.7299785614013672, 'step': 617},\n",
       "  {'loss': 0.1934536099433899, 'step': 618},\n",
       "  {'loss': 0.5612472295761108, 'step': 619},\n",
       "  {'loss': 0.767642617225647, 'step': 620},\n",
       "  {'loss': 0.29670029878616333, 'step': 621},\n",
       "  {'loss': 0.5845476388931274, 'step': 622},\n",
       "  {'loss': 0.2734842896461487, 'step': 623},\n",
       "  {'loss': 0.9187129735946655, 'step': 624},\n",
       "  {'loss': 0.6074129343032837, 'step': 625},\n",
       "  {'loss': 0.5417864918708801, 'step': 626},\n",
       "  {'loss': 0.42777836322784424, 'step': 627},\n",
       "  {'loss': 0.5809995532035828, 'step': 628},\n",
       "  {'loss': 0.44498077034950256, 'step': 629},\n",
       "  {'loss': 1.4019197225570679, 'step': 630},\n",
       "  {'loss': 0.6488037109375, 'step': 631},\n",
       "  {'loss': 0.7850937843322754, 'step': 632},\n",
       "  {'loss': 0.3211047053337097, 'step': 633},\n",
       "  {'loss': 0.7651227712631226, 'step': 634},\n",
       "  {'loss': 1.034080147743225, 'step': 635},\n",
       "  {'loss': 0.5511719584465027, 'step': 636},\n",
       "  {'loss': 0.5509098768234253, 'step': 637},\n",
       "  {'loss': 0.43865126371383667, 'step': 638},\n",
       "  {'loss': 0.42371872067451477, 'step': 639},\n",
       "  {'loss': 0.6405777931213379, 'step': 640},\n",
       "  {'loss': 0.4174634516239166, 'step': 641},\n",
       "  {'loss': 1.2334011793136597, 'step': 642},\n",
       "  {'loss': 0.4374198913574219, 'step': 643},\n",
       "  {'loss': 0.24614757299423218, 'step': 644},\n",
       "  {'loss': 0.27295103669166565, 'step': 645},\n",
       "  {'loss': 0.6561369299888611, 'step': 646},\n",
       "  {'loss': 0.34018388390541077, 'step': 647},\n",
       "  {'loss': 0.23806461691856384, 'step': 648},\n",
       "  {'loss': 0.1573779433965683, 'step': 649},\n",
       "  {'loss': 0.20607979595661163, 'step': 650},\n",
       "  {'loss': 0.36870908737182617, 'step': 651},\n",
       "  {'loss': 0.46937620639801025, 'step': 652},\n",
       "  {'loss': 0.8082268834114075, 'step': 653},\n",
       "  {'loss': 0.2793513834476471, 'step': 654},\n",
       "  {'loss': 0.588105320930481, 'step': 655},\n",
       "  {'loss': 0.16445432603359222, 'step': 656},\n",
       "  {'loss': 0.33814185857772827, 'step': 657},\n",
       "  {'loss': 0.2989096939563751, 'step': 658},\n",
       "  {'loss': 0.13748082518577576, 'step': 659},\n",
       "  {'loss': 0.09540136158466339, 'step': 660},\n",
       "  {'loss': 0.5072324275970459, 'step': 661},\n",
       "  {'loss': 0.8497253656387329, 'step': 662},\n",
       "  {'loss': 0.24970105290412903, 'step': 663},\n",
       "  {'loss': 0.23211392760276794, 'step': 664},\n",
       "  {'loss': 0.6282534003257751, 'step': 665},\n",
       "  {'loss': 0.47378844022750854, 'step': 666},\n",
       "  {'loss': 1.3931432962417603, 'step': 667},\n",
       "  {'loss': 0.24246317148208618, 'step': 668},\n",
       "  {'loss': 0.7684022784233093, 'step': 669},\n",
       "  {'loss': 1.227201223373413, 'step': 670},\n",
       "  {'loss': 0.20361927151679993, 'step': 671},\n",
       "  {'loss': 0.27711713314056396, 'step': 672},\n",
       "  {'loss': 0.5857570171356201, 'step': 673},\n",
       "  {'loss': 1.0091618299484253, 'step': 674},\n",
       "  {'loss': 0.8485686779022217, 'step': 675},\n",
       "  {'loss': 0.6987231969833374, 'step': 676},\n",
       "  {'loss': 0.5229541063308716, 'step': 677},\n",
       "  {'loss': 0.43307286500930786, 'step': 678},\n",
       "  {'loss': 0.8656023740768433, 'step': 679},\n",
       "  {'loss': 0.32420432567596436, 'step': 680},\n",
       "  {'loss': 0.328607976436615, 'step': 681},\n",
       "  {'loss': 0.2824121415615082, 'step': 682},\n",
       "  {'loss': 0.44492995738983154, 'step': 683},\n",
       "  {'loss': 0.11056504398584366, 'step': 684},\n",
       "  {'loss': 0.565279483795166, 'step': 685},\n",
       "  {'loss': 0.6654849648475647, 'step': 686},\n",
       "  {'loss': 0.8588385581970215, 'step': 687},\n",
       "  {'loss': 0.8150666952133179, 'step': 688},\n",
       "  {'loss': 0.6920920610427856, 'step': 689},\n",
       "  {'loss': 1.0386767387390137, 'step': 690},\n",
       "  {'loss': 0.8888327479362488, 'step': 691},\n",
       "  {'loss': 0.5123991370201111, 'step': 692},\n",
       "  {'loss': 0.8940508961677551, 'step': 693},\n",
       "  {'loss': 0.36773765087127686, 'step': 694},\n",
       "  {'loss': 0.3119387626647949, 'step': 695},\n",
       "  {'loss': 0.6542582511901855, 'step': 696},\n",
       "  {'loss': 0.6811360120773315, 'step': 697},\n",
       "  {'loss': 0.4271717965602875, 'step': 698},\n",
       "  {'loss': 0.53920978307724, 'step': 699},\n",
       "  {'loss': 0.531670868396759, 'step': 700},\n",
       "  {'loss': 0.3068315386772156, 'step': 701},\n",
       "  {'loss': 0.974384605884552, 'step': 702},\n",
       "  {'loss': 0.22934496402740479, 'step': 703},\n",
       "  {'loss': 0.36446166038513184, 'step': 704},\n",
       "  {'loss': 0.2796107232570648, 'step': 705},\n",
       "  {'loss': 0.4034745693206787, 'step': 706},\n",
       "  {'loss': 0.2552053928375244, 'step': 707},\n",
       "  {'loss': 0.238311767578125, 'step': 708},\n",
       "  {'loss': 0.6889058947563171, 'step': 709},\n",
       "  {'loss': 0.1611940562725067, 'step': 710},\n",
       "  {'loss': 0.6348559260368347, 'step': 711},\n",
       "  {'loss': 0.9852410554885864, 'step': 712},\n",
       "  {'loss': 0.20540550351142883, 'step': 713},\n",
       "  {'loss': 0.50202876329422, 'step': 714},\n",
       "  {'loss': 0.20530201494693756, 'step': 715},\n",
       "  {'loss': 0.2850545644760132, 'step': 716},\n",
       "  {'loss': 0.3184240460395813, 'step': 717},\n",
       "  {'loss': 0.39638224244117737, 'step': 718},\n",
       "  {'loss': 0.5068721771240234, 'step': 719},\n",
       "  {'loss': 0.4174690246582031, 'step': 720},\n",
       "  {'loss': 0.22545179724693298, 'step': 721},\n",
       "  {'loss': 0.3744395077228546, 'step': 722},\n",
       "  {'loss': 0.5137915015220642, 'step': 723},\n",
       "  {'loss': 0.7516202330589294, 'step': 724},\n",
       "  {'loss': 0.23942939937114716, 'step': 725},\n",
       "  {'loss': 0.6388601064682007, 'step': 726},\n",
       "  {'loss': 0.21702012419700623, 'step': 727},\n",
       "  {'loss': 0.33496713638305664, 'step': 728},\n",
       "  {'loss': 0.6725891828536987, 'step': 729},\n",
       "  {'loss': 0.30694133043289185, 'step': 730},\n",
       "  {'loss': 0.8316963911056519, 'step': 731},\n",
       "  {'loss': 0.40907585620880127, 'step': 732},\n",
       "  {'loss': 0.6265478134155273, 'step': 733},\n",
       "  {'loss': 0.6556421518325806, 'step': 734},\n",
       "  {'loss': 0.3109520673751831, 'step': 735},\n",
       "  {'loss': 0.31065183877944946, 'step': 736},\n",
       "  {'loss': 0.37067824602127075, 'step': 737},\n",
       "  {'loss': 0.44376152753829956, 'step': 738},\n",
       "  {'loss': 0.15548540651798248, 'step': 739},\n",
       "  {'loss': 0.9877374768257141, 'step': 740},\n",
       "  {'loss': 0.42512810230255127, 'step': 741},\n",
       "  {'loss': 0.3183766305446625, 'step': 742},\n",
       "  {'loss': 0.20703180134296417, 'step': 743},\n",
       "  {'loss': 0.4994712471961975, 'step': 744},\n",
       "  {'loss': 0.2702045142650604, 'step': 745},\n",
       "  {'loss': 0.5705768465995789, 'step': 746},\n",
       "  {'loss': 0.3439207673072815, 'step': 747},\n",
       "  {'loss': 1.3620452880859375, 'step': 748},\n",
       "  {'loss': 0.2623386085033417, 'step': 749},\n",
       "  {'loss': 0.17729508876800537, 'step': 750},\n",
       "  {'loss': 0.27050870656967163, 'step': 751},\n",
       "  {'loss': 0.28681015968322754, 'step': 752},\n",
       "  {'loss': 0.27412843704223633, 'step': 753},\n",
       "  {'loss': 0.24522101879119873, 'step': 754},\n",
       "  {'loss': 0.8343207240104675, 'step': 755},\n",
       "  {'loss': 0.23945197463035583, 'step': 756},\n",
       "  {'loss': 0.2786635160446167, 'step': 757},\n",
       "  {'loss': 0.18974146246910095, 'step': 758},\n",
       "  {'loss': 0.9664179086685181, 'step': 759},\n",
       "  {'loss': 0.3504537045955658, 'step': 760},\n",
       "  {'loss': 0.2705896496772766, 'step': 761},\n",
       "  {'loss': 0.26125776767730713, 'step': 762},\n",
       "  {'loss': 0.5144550204277039, 'step': 763},\n",
       "  {'loss': 0.298224538564682, 'step': 764},\n",
       "  {'loss': 0.5715214014053345, 'step': 765},\n",
       "  {'loss': 0.216415137052536, 'step': 766},\n",
       "  {'loss': 0.844234049320221, 'step': 767},\n",
       "  {'loss': 0.2916952967643738, 'step': 768},\n",
       "  {'loss': 0.8489786386489868, 'step': 769},\n",
       "  {'loss': 0.33897000551223755, 'step': 770},\n",
       "  {'loss': 0.17287060618400574, 'step': 771},\n",
       "  {'loss': 0.14723244309425354, 'step': 772},\n",
       "  {'loss': 0.3827136754989624, 'step': 773},\n",
       "  {'loss': 0.46633949875831604, 'step': 774},\n",
       "  {'loss': 0.3453948497772217, 'step': 775},\n",
       "  {'loss': 0.3863323926925659, 'step': 776},\n",
       "  {'loss': 0.6058428287506104, 'step': 777},\n",
       "  {'loss': 0.5872781276702881, 'step': 778},\n",
       "  {'loss': 0.1620240956544876, 'step': 779},\n",
       "  {'loss': 0.24964086711406708, 'step': 780},\n",
       "  {'loss': 0.5930547714233398, 'step': 781},\n",
       "  {'loss': 0.10267379879951477, 'step': 782},\n",
       "  {'loss': 0.440679669380188, 'step': 783},\n",
       "  {'loss': 0.8151483535766602, 'step': 784},\n",
       "  {'loss': 0.46101778745651245, 'step': 785},\n",
       "  {'loss': 0.3349529504776001, 'step': 786},\n",
       "  {'loss': 0.5380361080169678, 'step': 787},\n",
       "  {'loss': 0.9128109812736511, 'step': 788},\n",
       "  {'loss': 0.6875797510147095, 'step': 789},\n",
       "  {'loss': 0.5938241481781006, 'step': 790},\n",
       "  {'loss': 0.3710932433605194, 'step': 791},\n",
       "  {'loss': 0.31503164768218994, 'step': 792},\n",
       "  {'loss': 0.3220154941082001, 'step': 793},\n",
       "  {'loss': 0.4852428734302521, 'step': 794},\n",
       "  {'loss': 0.19543719291687012, 'step': 795},\n",
       "  {'loss': 0.5709378123283386, 'step': 796},\n",
       "  {'loss': 0.15663155913352966, 'step': 797},\n",
       "  {'loss': 0.2884368598461151, 'step': 798},\n",
       "  {'loss': 0.5978564023971558, 'step': 799},\n",
       "  {'loss': 0.20874127745628357, 'step': 800},\n",
       "  {'loss': 1.034468173980713, 'step': 801},\n",
       "  {'loss': 1.261147379875183, 'step': 802},\n",
       "  {'loss': 0.441754013299942, 'step': 803},\n",
       "  {'loss': 0.471076101064682, 'step': 804},\n",
       "  {'loss': 0.3240356147289276, 'step': 805},\n",
       "  {'loss': 0.09814108163118362, 'step': 806},\n",
       "  {'loss': 0.48340898752212524, 'step': 807},\n",
       "  {'loss': 0.9827935099601746, 'step': 808},\n",
       "  {'loss': 0.6936443448066711, 'step': 809},\n",
       "  {'loss': 0.4824836850166321, 'step': 810},\n",
       "  {'loss': 0.25998982787132263, 'step': 811},\n",
       "  {'loss': 0.34035998582839966, 'step': 812},\n",
       "  {'loss': 0.24072429537773132, 'step': 813},\n",
       "  {'loss': 0.26240986585617065, 'step': 814},\n",
       "  {'loss': 0.4629959166049957, 'step': 815},\n",
       "  {'loss': 0.2998746633529663, 'step': 816},\n",
       "  {'loss': 0.23797330260276794, 'step': 817},\n",
       "  {'loss': 0.25106075406074524, 'step': 818},\n",
       "  {'loss': 1.0333980321884155, 'step': 819},\n",
       "  {'loss': 0.6608438491821289, 'step': 820},\n",
       "  {'loss': 1.7379915714263916, 'step': 821},\n",
       "  {'loss': 0.7197400331497192, 'step': 822},\n",
       "  {'loss': 0.23042243719100952, 'step': 823},\n",
       "  {'loss': 0.41792434453964233, 'step': 824},\n",
       "  {'loss': 0.36627379059791565, 'step': 825},\n",
       "  {'loss': 0.47536423802375793, 'step': 826},\n",
       "  {'loss': 0.39976149797439575, 'step': 827},\n",
       "  {'loss': 0.5787802934646606, 'step': 828},\n",
       "  {'loss': 1.0036978721618652, 'step': 829},\n",
       "  {'loss': 0.4103506803512573, 'step': 830},\n",
       "  {'loss': 0.6780318021774292, 'step': 831},\n",
       "  {'loss': 1.5079500675201416, 'step': 832},\n",
       "  {'loss': 0.1483439803123474, 'step': 833},\n",
       "  {'loss': 0.4567374885082245, 'step': 834},\n",
       "  {'loss': 0.2084486484527588, 'step': 835},\n",
       "  {'loss': 0.43228915333747864, 'step': 836},\n",
       "  {'loss': 0.43600863218307495, 'step': 837},\n",
       "  {'loss': 0.38649827241897583, 'step': 838},\n",
       "  {'loss': 0.7535992860794067, 'step': 839},\n",
       "  {'loss': 0.36888277530670166, 'step': 840},\n",
       "  {'loss': 0.456891268491745, 'step': 841},\n",
       "  {'loss': 0.26496779918670654, 'step': 842},\n",
       "  {'loss': 0.39521393179893494, 'step': 843},\n",
       "  {'loss': 0.47871994972229004, 'step': 844},\n",
       "  {'loss': 0.6374897360801697, 'step': 845},\n",
       "  {'loss': 0.6694724559783936, 'step': 846},\n",
       "  {'loss': 0.5405259132385254, 'step': 847},\n",
       "  {'loss': 0.5522815585136414, 'step': 848},\n",
       "  {'loss': 0.287125825881958, 'step': 849},\n",
       "  {'loss': 0.7610099911689758, 'step': 850},\n",
       "  {'loss': 0.11248461902141571, 'step': 851},\n",
       "  {'loss': 0.14191357791423798, 'step': 852},\n",
       "  {'loss': 0.45203733444213867, 'step': 853},\n",
       "  {'loss': 0.31051939725875854, 'step': 854},\n",
       "  {'loss': 1.6941659450531006, 'step': 855},\n",
       "  {'loss': 0.24291253089904785, 'step': 856},\n",
       "  {'loss': 0.4545477628707886, 'step': 857},\n",
       "  {'loss': 0.4603075385093689, 'step': 858},\n",
       "  {'loss': 0.35778698325157166, 'step': 859},\n",
       "  {'loss': 0.7098994255065918, 'step': 860},\n",
       "  {'loss': 0.4164564609527588, 'step': 861},\n",
       "  {'loss': 0.5531768202781677, 'step': 862},\n",
       "  {'loss': 0.624580442905426, 'step': 863},\n",
       "  {'loss': 0.4467734694480896, 'step': 864},\n",
       "  {'loss': 0.20079612731933594, 'step': 865},\n",
       "  {'loss': 0.5344468355178833, 'step': 866},\n",
       "  {'loss': 0.8690841197967529, 'step': 867},\n",
       "  {'loss': 1.727402687072754, 'step': 868},\n",
       "  {'loss': 0.2689225673675537, 'step': 869},\n",
       "  {'loss': 0.9561260938644409, 'step': 870},\n",
       "  {'loss': 0.22904419898986816, 'step': 871},\n",
       "  {'loss': 0.43832749128341675, 'step': 872},\n",
       "  {'loss': 0.5828496813774109, 'step': 873},\n",
       "  {'loss': 0.5978007912635803, 'step': 874},\n",
       "  {'loss': 0.641772985458374, 'step': 875},\n",
       "  {'loss': 0.4007037281990051, 'step': 876},\n",
       "  {'loss': 1.1913033723831177, 'step': 877},\n",
       "  {'loss': 1.1082720756530762, 'step': 878},\n",
       "  {'loss': 0.5080684423446655, 'step': 879},\n",
       "  {'loss': 0.656653642654419, 'step': 880},\n",
       "  {'loss': 0.8265859484672546, 'step': 881},\n",
       "  {'loss': 0.7841877937316895, 'step': 882},\n",
       "  {'loss': 0.9400695562362671, 'step': 883},\n",
       "  {'loss': 0.3953152894973755, 'step': 884},\n",
       "  {'loss': 0.20260635018348694, 'step': 885},\n",
       "  {'loss': 0.6685603857040405, 'step': 886},\n",
       "  {'loss': 0.384994775056839, 'step': 887},\n",
       "  {'loss': 0.46324944496154785, 'step': 888},\n",
       "  {'loss': 0.3003442883491516, 'step': 889},\n",
       "  {'loss': 0.9511847496032715, 'step': 890},\n",
       "  {'loss': 0.49964672327041626, 'step': 891},\n",
       "  {'loss': 0.37973859906196594, 'step': 892},\n",
       "  {'loss': 0.3235388994216919, 'step': 893},\n",
       "  {'loss': 0.5213683247566223, 'step': 894},\n",
       "  {'loss': 0.19101636111736298, 'step': 895},\n",
       "  {'loss': 0.5630402565002441, 'step': 896},\n",
       "  {'loss': 0.4158928394317627, 'step': 897},\n",
       "  {'loss': 0.10903145372867584, 'step': 898},\n",
       "  {'loss': 0.17756304144859314, 'step': 899},\n",
       "  {'loss': 0.32602131366729736, 'step': 900},\n",
       "  {'loss': 0.37779000401496887, 'step': 901},\n",
       "  {'loss': 0.18033172190189362, 'step': 902},\n",
       "  {'loss': 0.6589343547821045, 'step': 903},\n",
       "  {'loss': 0.31624945998191833, 'step': 904},\n",
       "  {'loss': 0.4668336510658264, 'step': 905},\n",
       "  {'loss': 0.3366492986679077, 'step': 906},\n",
       "  {'loss': 0.388346791267395, 'step': 907},\n",
       "  {'loss': 0.35835403203964233, 'step': 908},\n",
       "  {'loss': 0.1470472365617752, 'step': 909},\n",
       "  {'loss': 0.5033897757530212, 'step': 910},\n",
       "  {'loss': 0.22174032032489777, 'step': 911},\n",
       "  {'loss': 0.1771659553050995, 'step': 912},\n",
       "  {'loss': 0.9525216817855835, 'step': 913},\n",
       "  {'loss': 0.2636865973472595, 'step': 914},\n",
       "  {'loss': 0.2516530156135559, 'step': 915},\n",
       "  {'loss': 0.23188799619674683, 'step': 916},\n",
       "  {'loss': 0.18369755148887634, 'step': 917},\n",
       "  {'loss': 0.43494540452957153, 'step': 918},\n",
       "  {'loss': 0.8961716890335083, 'step': 919},\n",
       "  {'loss': 0.9056745767593384, 'step': 920},\n",
       "  {'loss': 0.18049387633800507, 'step': 921},\n",
       "  {'loss': 0.4485345184803009, 'step': 922},\n",
       "  {'loss': 1.6106430292129517, 'step': 923},\n",
       "  {'loss': 0.6623703241348267, 'step': 924},\n",
       "  {'loss': 0.19931749999523163, 'step': 925},\n",
       "  {'loss': 0.27405521273612976, 'step': 926},\n",
       "  {'loss': 0.5636197328567505, 'step': 927},\n",
       "  {'loss': 0.19123061001300812, 'step': 928},\n",
       "  {'loss': 0.20800907909870148, 'step': 929},\n",
       "  {'loss': 0.7046622037887573, 'step': 930},\n",
       "  {'loss': 0.9340342283248901, 'step': 931},\n",
       "  {'loss': 0.15470175445079803, 'step': 932},\n",
       "  {'loss': 0.2138538807630539, 'step': 933},\n",
       "  {'loss': 0.2071187049150467, 'step': 934},\n",
       "  {'loss': 0.41056904196739197, 'step': 935},\n",
       "  {'loss': 0.31182539463043213, 'step': 936},\n",
       "  {'loss': 0.34045886993408203, 'step': 937},\n",
       "  {'loss': 0.5590673685073853, 'step': 938},\n",
       "  {'loss': 0.5226931571960449, 'step': 939},\n",
       "  {'loss': 0.2006971836090088, 'step': 940},\n",
       "  {'loss': 0.6852822303771973, 'step': 941},\n",
       "  {'loss': 0.44601112604141235, 'step': 942},\n",
       "  {'loss': 0.3201307952404022, 'step': 943},\n",
       "  {'loss': 0.1509716957807541, 'step': 944},\n",
       "  {'loss': 0.39952290058135986, 'step': 945},\n",
       "  {'loss': 1.4202860593795776, 'step': 946},\n",
       "  {'loss': 0.30299535393714905, 'step': 947},\n",
       "  {'loss': 0.3945021629333496, 'step': 948},\n",
       "  {'loss': 0.366863489151001, 'step': 949},\n",
       "  {'loss': 0.16677623987197876, 'step': 950},\n",
       "  {'loss': 0.2344306856393814, 'step': 951},\n",
       "  {'loss': 0.8538309335708618, 'step': 952},\n",
       "  {'loss': 0.6099393963813782, 'step': 953},\n",
       "  {'loss': 0.31605157256126404, 'step': 954},\n",
       "  {'loss': 0.3425181806087494, 'step': 955},\n",
       "  {'loss': 0.34559163451194763, 'step': 956},\n",
       "  {'loss': 0.15120097994804382, 'step': 957},\n",
       "  {'loss': 0.5518040657043457, 'step': 958},\n",
       "  {'loss': 0.7693026065826416, 'step': 959},\n",
       "  {'loss': 0.48336368799209595, 'step': 960},\n",
       "  {'loss': 0.20658501982688904, 'step': 961},\n",
       "  {'loss': 0.9754050374031067, 'step': 962},\n",
       "  {'loss': 0.6513017416000366, 'step': 963},\n",
       "  {'loss': 0.6823093891143799, 'step': 964},\n",
       "  {'loss': 0.29853495955467224, 'step': 965},\n",
       "  {'loss': 0.41285502910614014, 'step': 966},\n",
       "  {'loss': 0.2986588180065155, 'step': 967},\n",
       "  {'loss': 0.19558022916316986, 'step': 968},\n",
       "  {'loss': 0.4036579132080078, 'step': 969},\n",
       "  {'loss': 0.22708655893802643, 'step': 970},\n",
       "  {'loss': 0.33966392278671265, 'step': 971},\n",
       "  {'loss': 0.21397514641284943, 'step': 972},\n",
       "  {'loss': 0.23161645233631134, 'step': 973},\n",
       "  {'loss': 0.17368640005588531, 'step': 974},\n",
       "  {'loss': 0.22737380862236023, 'step': 975},\n",
       "  {'loss': 0.28634631633758545, 'step': 976},\n",
       "  {'loss': 0.5578152537345886, 'step': 977},\n",
       "  {'loss': 0.567471444606781, 'step': 978},\n",
       "  {'loss': 0.297316312789917, 'step': 979},\n",
       "  {'loss': 0.37768757343292236, 'step': 980},\n",
       "  {'loss': 0.7089220881462097, 'step': 981},\n",
       "  {'loss': 0.4865363836288452, 'step': 982},\n",
       "  {'loss': 0.2956595718860626, 'step': 983},\n",
       "  {'loss': 0.35482415556907654, 'step': 984},\n",
       "  {'loss': 0.3238692283630371, 'step': 985},\n",
       "  {'loss': 0.44943901896476746, 'step': 986},\n",
       "  {'loss': 0.4743900001049042, 'step': 987},\n",
       "  {'loss': 0.6229766607284546, 'step': 988},\n",
       "  {'loss': 0.8890350461006165, 'step': 989},\n",
       "  {'loss': 0.3040221035480499, 'step': 990},\n",
       "  {'loss': 0.12763378024101257, 'step': 991},\n",
       "  {'loss': 0.25432100892066956, 'step': 992},\n",
       "  {'loss': 0.8674096465110779, 'step': 993},\n",
       "  {'loss': 0.3368012011051178, 'step': 994},\n",
       "  {'loss': 0.6439736485481262, 'step': 995},\n",
       "  {'loss': 0.30920690298080444, 'step': 996},\n",
       "  {'loss': 0.34410032629966736, 'step': 997},\n",
       "  {'loss': 0.8810059428215027, 'step': 998},\n",
       "  {'loss': 0.16582302749156952, 'step': 999},\n",
       "  ...],\n",
       " 'val': [{'loss': np.float64(6.296770273653929), 'step': 0},\n",
       "  {'loss': np.float64(0.5236712124598913), 'step': 726},\n",
       "  {'loss': np.float64(0.4565402700388727), 'step': 1452},\n",
       "  {'loss': np.float64(0.43434173062690035), 'step': 2178},\n",
       "  {'loss': np.float64(0.4254533759325989), 'step': 2904},\n",
       "  {'loss': np.float64(0.41638283813295285), 'step': 3630},\n",
       "  {'loss': np.float64(0.4088059758290279), 'step': 4356},\n",
       "  {'loss': np.float64(0.4088185678028371), 'step': 5082},\n",
       "  {'loss': np.float64(0.39316253367164905), 'step': 5808},\n",
       "  {'loss': np.float64(0.42639134242391785), 'step': 6534},\n",
       "  {'loss': np.float64(0.38276097424759353), 'step': 7260},\n",
       "  {'loss': np.float64(0.3790162411972511), 'step': 7986},\n",
       "  {'loss': np.float64(0.3839347798469638), 'step': 8712},\n",
       "  {'loss': np.float64(0.3760226208962931), 'step': 9438},\n",
       "  {'loss': np.float64(0.36847982118444994), 'step': 10164},\n",
       "  {'loss': np.float64(0.3624126446579606), 'step': 10890},\n",
       "  {'loss': np.float64(0.3706409706741818), 'step': 11616},\n",
       "  {'loss': np.float64(0.3697986975312233), 'step': 12342},\n",
       "  {'loss': np.float64(0.3534766701935244), 'step': 13068},\n",
       "  {'loss': np.float64(0.3632656694505333), 'step': 13794},\n",
       "  {'loss': np.float64(0.3512174482495824), 'step': 14520},\n",
       "  {'loss': np.float64(0.3489753606398244), 'step': 15246},\n",
       "  {'loss': np.float64(0.35266412871558805), 'step': 15972},\n",
       "  {'loss': np.float64(0.34239123598480026), 'step': 16698},\n",
       "  {'loss': np.float64(0.34067794779115473), 'step': 17424},\n",
       "  {'loss': np.float64(0.3403179065655332), 'step': 18150},\n",
       "  {'loss': np.float64(0.3440746708103448), 'step': 18876},\n",
       "  {'loss': np.float64(0.33347121299790944), 'step': 19602},\n",
       "  {'loss': np.float64(0.3397171890193766), 'step': 20328},\n",
       "  {'loss': np.float64(0.3327006791710607), 'step': 21054},\n",
       "  {'loss': np.float64(0.3313806351458977), 'step': 21780},\n",
       "  {'loss': np.float64(0.32840008211653093), 'step': 22506},\n",
       "  {'loss': np.float64(0.3286387401917749), 'step': 23232},\n",
       "  {'loss': np.float64(0.328172996470874), 'step': 23958},\n",
       "  {'loss': np.float64(0.32558490372886345), 'step': 24684},\n",
       "  {'loss': np.float64(0.32552856416249076), 'step': 25410},\n",
       "  {'loss': np.float64(0.32588032867051353), 'step': 26136},\n",
       "  {'loss': np.float64(0.32481724855082095), 'step': 26862},\n",
       "  {'loss': np.float64(0.33287288310114016), 'step': 27588},\n",
       "  {'loss': np.float64(0.33199254115504667), 'step': 28314},\n",
       "  {'loss': np.float64(0.3311056499023083), 'step': 29040},\n",
       "  {'loss': np.float64(0.321908591977082), 'step': 29766},\n",
       "  {'loss': np.float64(0.32350420762499993), 'step': 30492},\n",
       "  {'loss': np.float64(0.6410459018935842), 'step': 31218},\n",
       "  {'loss': np.float64(0.3288693818579282), 'step': 31944},\n",
       "  {'loss': np.float64(0.3201525012138954), 'step': 32670},\n",
       "  {'loss': np.float64(0.31676266579465434), 'step': 33396},\n",
       "  {'loss': np.float64(0.32339244831568936), 'step': 34122},\n",
       "  {'loss': np.float64(0.32329615153187563), 'step': 34848},\n",
       "  {'loss': np.float64(0.32873988637993157), 'step': 35574},\n",
       "  {'loss': np.float64(0.3147452718401251), 'step': 36300},\n",
       "  {'loss': np.float64(0.32349208710053245), 'step': 37026},\n",
       "  {'loss': np.float64(0.32041439527938187), 'step': 37752},\n",
       "  {'loss': np.float64(0.31699847386888236), 'step': 38478},\n",
       "  {'loss': np.float64(0.3255085086157499), 'step': 39204},\n",
       "  {'loss': np.float64(0.32486973508946165), 'step': 39930},\n",
       "  {'loss': np.float64(0.3203623639034831), 'step': 40656},\n",
       "  {'loss': np.float64(0.32492418459439576), 'step': 41382},\n",
       "  {'loss': np.float64(0.32014471929797456), 'step': 42108},\n",
       "  {'loss': np.float64(0.31784438526581144), 'step': 42834},\n",
       "  {'loss': np.float64(0.32332427380991374), 'step': 43560}]}"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 49
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:55:34.802025Z",
     "start_time": "2025-03-06T10:55:34.670314Z"
    }
   },
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    for idx, item in enumerate(train_df.columns):\n",
    "        plt.plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        plt.plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        plt.grid()\n",
    "        plt.legend()\n",
    "        # plt.xticks(range(0, train_df.index[-1], 10*sample_step), range(0, train_df.index[-1], 10*sample_step))\n",
    "        plt.xlabel(\"step\")\n",
    "\n",
    "        plt.show()\n",
    "\n",
    "plot_learning_curves(record)  #横坐标是 steps"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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U1PF1atXizt27BAHDx4sDh482Hm7Y8ncmDFjxD179oi//fabGB8f73HJ3JNPPikePnxY/OCDDzwumeP/nrtnnnlGXLdunXjq1Clx37594jPPPCMKgiCuWLFCFEX2TbBxXRUiiuwfX5BFYCGKovjee++JqampokajEQcOHChu2bIl0E26rK1Zs0YEUOdy5513iqIoLTn917/+JSYmJoparVYcOXKkmJmZ6XYf58+fF6dOnSqGh4eLer1evOuuu8SysjK3Y/bu3SteddVVolarFVu3bi2++uqrddry7bffip07dxY1Go3Yo0cPcenSpc32vC8HnvoFgDh//nznMVVVVeKDDz4oRkdHizqdTpw8ebKYm5vrdj9ZWVni+PHjxdDQUDEuLk7829/+JprNZrdj1qxZI/bu3VvUaDRihw4d3B7Dgf977u6++26xbdu2okajEePj48WRI0c6gwpRZN8Em9qBBfvn0nHbdCIiIvKZy36OBREREQUPBhZERETkMwwsiIiIyGcYWBAREZHPMLAgIiIin2FgQURERD7DwIKIiIh8hoEFERER+QwDCyIiIvIZBhZE5JUZM2bgxhtvDHQziChIMbAgIiIin2FgQUQeff/990hLS0NoaChiY2MxatQoPPnkk/jiiy/w888/QxAECIKAtWvXAgBycnIwZcoUREVFISYmBpMmTUJWVpbz/hyZjjlz5iA+Ph56vR4PPPAATCZTYJ4gETULVaAbQETBJzc3F1OnTsVrr72GyZMno6ysDBs2bMAdd9yB7OxsGAwGzJ8/HwAQExMDs9mMsWPHYvDgwdiwYQNUKhVeeukljBs3Dvv27YNGowEArFq1CiEhIVi7di2ysrJw1113ITY2Fi+//HIgny4R+RADCyKqIzc3FxaLBTfddBPatm0LAEhLSwMAhIaGwmg0IikpyXn8V199BZvNhk8//RSCIAAA5s+fj6ioKKxduxZjxowBAGg0GsybNw86nQ49evTACy+8gCeffBIvvvgiFAomUInkgP/JRFRHeno6Ro4cibS0NNx6663473//iwsXLtR7/N69e3H8+HFEREQgPDwc4eHhiImJQXV1NU6cOOF2vzqdzvnz4MGDUV5ejpycnGZ9PkTkP8xYEFEdSqUSGRkZ2LRpE1asWIH33nsP//jHP7B161aPx5eXl6Nfv374+uuv69wWHx/f3M0loiDCwIKIPBIEAUOHDsXQoUPx7LPPom3btli8eDE0Gg2sVqvbsX379sU333yDhIQE6PX6eu9z7969qKqqQmhoKABgy5YtCA8PR0pKSrM+FyLyHw6FEFEdW7duxSuvvIIdO3YgOzsbP/74IwoLC9GtWze0a9cO+/btQ2ZmJoqKimA2mzF9+nTExcVh0qRJ2LBhA06dOoW1a9fi4YcfxpkzZ5z3azKZcM899+DQoUNYtmwZnnvuOcyaNYvzK4hkhBkLIqpDr9dj/fr1ePvtt2EwGNC2bVu8+eabGD9+PPr374+1a9eif//+KC8vx5o1azB8+HCsX78eTz/9NG666SaUlZWhdevWGDlypFsGY+TIkejUqROGDRsGo9GIqVOn4vnnnw/cEyUinxNEURQD3Qgikr8ZM2agpKQEP/30U6CbQkTNiPlHIiIi8hkGFkREROQzHAohIiIin2HGgoiIiHyGgQURERH5DAMLIiIi8hkGFkREROQzDCyIiIjIZxhYEBERkc8wsCAiIiKfYWBBREREPvP/iya2uVYvxeQAAAAASUVORK5CYII="
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 51
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 测试集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-06T10:57:29.824406Z",
     "start_time": "2025-03-06T10:57:29.611251Z"
    }
   },
   "source": [
    "model.eval()\n",
    "loss = evaluating(model, test_loader, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3261\n"
     ]
    }
   ],
   "execution_count": 52
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": ""
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
